import {
  Controller,
  Inject,
  Post,
  Get,
  Put,
  Body,
  Query,
  Param,
  File
} from "@midwayjs/core";
import { UploadFileInfo } from "@midwayjs/upload";
import { PrizeResultService } from "../service/prize.result.service";
import { Utils } from "../utils";
import {
  PrizeResultCreateDto,
  PrizeResultRedeemDto,
  PrizeResultListQueryDto,
  PrizeWinnerInfoDto,
  ShippingUpdateDto
} from "../dto/prize.result.dto";
import { ApiTags, ApiOperation } from "@midwayjs/swagger";

/**
 * 抽奖结果控制器
 * 提供抽奖码生成、验证、兑奖等API接口
 */
@ApiTags(["抽奖结果管理"])
@Controller("/auth-api/prize/result")
export class PrizeResultController {
  @Inject()
  prizeResultService: PrizeResultService;

  @Inject()
  utils: Utils;

  /**
   * 批量生成抽奖码
   * 固定生成10个抽奖码，根据提供的奖品权重分配生成数量
   */
  @ApiOperation({ summary: "批量生成抽奖码" })
  @Post("/batch-generate")
  async batchGenerate(@Body() dto: PrizeResultCreateDto) {
    const result = await this.prizeResultService.batchGenerate(dto);
    return this.utils.response.success(result);
  }

  @Post("/send/upload", { summary: "批量上传奖品派送信息" })
  async send_upload(@File() file: UploadFileInfo<any>) {
    const result = await this.prizeResultService.send_upload(file);
    return this.utils.response({
      ...result
    });
  }

  /**
   * 验证抽奖码
   */
  @ApiOperation({ summary: "验证抽奖码" })
  @Get("/verify/:code")
  async verifyLotteryCode(@Param("code") code: string) {
    const result = await this.prizeResultService.verifyLotteryCode(code);
    return this.utils.response.success(result);
  }

  /**
   * 兑换奖品
   */
  @ApiOperation({ summary: "兑换奖品" })
  @Post("/redeem")
  async redeemPrize(@Body() dto: PrizeResultRedeemDto) {
    const result = await this.prizeResultService.redeemPrize(dto);
    return this.utils.response.success(result);
  }

  /**
   * 获取抽奖结果列表
   */
  @ApiOperation({ summary: "获取抽奖结果列表" })
  @Get("/list")
  async list(@Query() query: PrizeResultListQueryDto) {
    const result = await this.prizeResultService.list(query);
    return this.utils.response.success(result);
  }

  /**
   * 分页获取抽奖结果列表
   */
  @ApiOperation({ summary: "分页获取抽奖结果列表" })
  @Get("/page")
  async page(
    @Query() query: PrizeResultListQueryDto,
    @Query("pageSize") pageSize?: number,
    @Query("current") current?: number
  ) {
    const result = await this.prizeResultService.page(
      query,
      pageSize ? parseInt(pageSize.toString(), 10) : 10,
      current ? parseInt(current.toString(), 10) : 1
    );
    return this.utils.response.success(result);
  }

  /**
   * 分页获取已使用抽奖码列表，按照是否发送奖品排序（未发件排前面）
   */
  @ApiOperation({ summary: "分页获取已使用抽奖码列表" })
  @Get("/page-used")
  async pageUsed(
    @Query() query: PrizeResultListQueryDto,
    @Query("pageSize") pageSize?: number,
    @Query("current") current?: number
  ) {
    const result = await this.prizeResultService.pageUsed(
      query,
      pageSize ? parseInt(pageSize.toString(), 10) : 10,
      current ? parseInt(current.toString(), 10) : 1
    );
    return this.utils.response.success(result);
  }

  /**
   * 获取已使用抽奖码列表
   */
  @ApiOperation({ summary: "获取已使用抽奖码列表" })
  @Get("/list-used")
  async listUsed(@Query() query: PrizeResultListQueryDto) {
    const result = await this.prizeResultService.listUsed(query);
    return this.utils.response.success(result);
  }

  /**
   * 获取抽奖结果详情
   */
  @ApiOperation({ summary: "获取抽奖结果详情" })
  @Get("/:id")
  async info(@Param("id") id: string) {
    const result = await this.prizeResultService.info(id);
    return this.utils.response.success(result);
  }

  /**
   * 根据抽奖码获取抽奖结果详情
   */
  @ApiOperation({ summary: "根据抽奖码获取抽奖结果详情" })
  @Get("/code/:code")
  async getByLotteryCode(@Param("code") code: string) {
    const result = await this.prizeResultService.getByLotteryCode(code);
    return this.utils.response.success(result);
  }

  /**
   * 导出抽奖结果列表
   */
  @ApiOperation({ summary: "导出抽奖结果列表" })
  @Get("/export")
  async exportList(@Query() query: PrizeResultListQueryDto) {
    const result = await this.prizeResultService.exportList(query);
    return this.utils.response.success(result);
  }

  /**
   * 更新物流信息
   */
  @ApiOperation({ summary: "更新物流信息" })
  @Put("/shipping")
  async updateShippingInfo(@Body() dto: ShippingUpdateDto) {
    const result = await this.prizeResultService.updateShippingInfo(dto);
    return this.utils.response.success(result);
  }

  /**
   * 批量更新物流信息
   */
  @ApiOperation({ summary: "批量更新物流信息" })
  @Put("/shipping/batch")
  async batchUpdateShippingInfo(
    @Body("resultIds") resultIds: string[],
    @Body("shippingInfo") shippingInfo: Omit<ShippingUpdateDto, "resultId">
  ) {
    const result = await this.prizeResultService.batchUpdateShippingInfo(
      resultIds,
      shippingInfo
    );
    return this.utils.response.success(result);
  }
}

/**
 * 面向用户的抽奖码接口
 */
@ApiTags(["用户抽奖"])
@Controller("/common-api/prize/lottery")
export class PrizeResultPublicController {
  @Inject()
  prizeResultService: PrizeResultService;

  @Inject()
  utils: Utils;

  /**
   * 验证抽奖码（公开接口）
   */
  @ApiOperation({ summary: "验证抽奖码（公开接口）" })
  @Get("/verify/:code")
  async verifyLotteryCode(@Param("code") code: string) {
    const result = await this.prizeResultService.verifyLotteryCode(code);
    return this.utils.response.success(result);
  }

  /**
   * 兑换奖品（公开接口）
   */
  @ApiOperation({ summary: "兑换奖品（公开接口）" })
  @Post("/redeem")
  async redeemPrize(@Body() dto: PrizeResultRedeemDto) {
    const result = await this.prizeResultService.redeemPrize(dto);
    return this.utils.response.success(result);
  }

  /**
   * 提交兑奖人信息（公开接口）
   */
  @ApiOperation({ summary: "提交兑奖人信息（公开接口）" })
  @Post("/submit-info")
  async submitWinnerInfo(@Body() dto: PrizeWinnerInfoDto) {
    const result = await this.prizeResultService.updateWinnerInfo(dto);
    if (result.success) {
      return this.utils.response.success(result);
    } else {
      return this.utils.response.fail(result);
    }
  }

  /**
   * 根据兑奖码查询抽奖码信息（公开接口）
   */
  @ApiOperation({ summary: "根据兑奖码查询抽奖码信息（公开接口）" })
  @Get("/code/:code")
  async getByLotteryCode(@Param("code") code: string) {
    const result = await this.prizeResultService.getByLotteryCode(code);
    return this.utils.response.success(result);
  }
}
